﻿using System;
using System.Reflection;
using System.Runtime.Serialization;

namespace GatewayUtil
{
    /// <summary>
    /// Binder class to avoid assembly version mismatch
    /// </summary>
    public class AssemblySerializationBinder : SerializationBinder
    {
        private Assembly[] availableAssemblies;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="availableAssemblies"></param>
        public AssemblySerializationBinder(Assembly[] availableAssemblies)
        {
            this.availableAssemblies = availableAssemblies;
        }

        /// <summary>
        /// Bind to type by own way :-)
        /// </summary>
        /// <param name="assemblyName">Name of DLL where is located the Type, e.g. Agents (without ".DLL"!)</param>
        /// <param name="typeName">The Type name = class name</param>
        /// <returns></returns>
        public override Type BindToType(System.String assemblyName, System.String typeName)
        {
            if (assemblyName == null)
            {
                return bindSlower(typeName);
            }
            else return bindFaster(assemblyName, typeName);

        }

        private Type bindSlower(string typeName)
        {
            for (int i = 0; i < availableAssemblies.Length; i++)
            {
                Type[] types = availableAssemblies[i].GetTypes();
                for (int j = 0; j < types.Length; j++)
                {
                    if (types[j].Name == typeName)
                        return types[j];
                }
            }
            return null;
        }

        private Type bindFaster(string assemblyName, string typeName)
        {
            assemblyName = assemblyName + ".DLL";
            for (int i = 0; i < availableAssemblies.Length; i++)
            {
                if (availableAssemblies[i].ManifestModule.Name.CompareTo(assemblyName) == 0)
                {
                    Type[] types = availableAssemblies[i].GetTypes();
                    for (int j = 0; j < types.Length; j++)
                    {
                        if (types[j].Name == typeName)
                            return types[j];
                    }
                }
            }
            return null;

        }
    }
}
